﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using ERPStore.Monitor.Models;

namespace ERPStore.Monitor.Services
{
	public class TasksListner
	{
		Models.MonitoredApplication m_Settings;
		IHandler m_Handler;

		public TasksListner(Models.MonitoredApplication settings)
		{
			m_Settings = settings;
		}

		public event Action<string> MessageReceived;
		public event Action ListChanged;
		public event Action<Exception> Error;
		public event Action<ERPStore.Tasks.ViewModels.Task, string> AddTask;
		public event Action<ERPStore.Tasks.ViewModels.Task, string> UpdateTask;
		public event Action<string, string, string> TaskStarted;
		public event Action<string, string, string> TaskTerminated;
		public string ApiUrl
		{
			get
			{
				return m_Settings.ApiServiceUrl;
			}
		}

		public void Start()
		{
			// m_TaskThread = new System.Threading.Thread(StartTasksListener);
			// m_TaskThread.Start();
			StartTasksListener();
		}

		public void Stop()
		{
		}

		public void ForceTask(string taskName)
		{
			var url = string.Format("{0}/api/tasksapi/ForceTask/{1}", m_Settings.ApiServiceUrl.TrimEnd('/'), taskName);

			var httpClient = new HttpClient();
			httpClient.DefaultRequestHeaders.Add("ApiKey", m_Settings.ApiKey);
			httpClient.GetStringAsync(url).ContinueWith((response) =>
			{
				if (response.Exception != null)
				{
					if (Error != null)
					{
						Error(response.Exception);
					}
				}
			}).Wait(5 * 1000);

		}

		private void StartTasksListener()
		{
			var list = GetList();
			foreach (var item in list)
			{
				if (AddTask != null)
				{
					AddTask(item, m_Settings.ApiServiceUrl);
				}
			}

			m_Handler = new SignalRHandler();
			m_Handler.Received += new Action<string>(Message_Received);
			m_Handler.Exception += (error) =>
			{
				if (Error != null)
				{
					Error(error);
				}
			};

			m_Handler.Start(m_Settings, "tasks", "tasklistner");

		}

		private void Message_Received(string tm)
		{
			if (tm == null
				|| tm.Trim() == string.Empty)
			{
				return;
			}

			if (tm != null)
			{
				if (tm.StartsWith("cmd|"))
				{
					RunCommand(tm);
				}
				else
				{
					if (MessageReceived != null)
					{
						MessageReceived(tm);
					}
				}
			}
		}

		public void RunCommand(string cmd)
		{
			var prms = cmd.Replace("cmd|", "").Split(',');
			switch (prms[0])
			{
				case "timer_elapsed" :
					var list = GetList();
					foreach (var item in list)
					{
						if (UpdateTask != null)
						{
							UpdateTask(item, m_Settings.ApiServiceUrl);
						}
					}
					break;
				case "started" :
					if (TaskStarted != null)
					{
						var name = prms[1].Split(':')[1];
						var machineName = prms[2].Split(':')[1];
						var hostName = prms[3].Split(':')[1];
						TaskStarted(name, machineName, hostName);
					}
					break;
				case "failed" :

					break;
				case "finished" :
					if (TaskTerminated != null)
					{
						var name = prms[1].Split(':')[1];
						var machineName = prms[2].Split(':')[1];
						var hostName = prms[3].Split(':')[1];
						TaskTerminated(name, machineName, hostName);
					}
					break;
				default:
					break;
			}
			if (ListChanged != null)
			{
				ListChanged();
			}
		}

		private List<ERPStore.Tasks.ViewModels.Task> GetList()
		{
			var url = string.Format("{0}/api/tasksapi/GetList", m_Settings.ApiServiceUrl.TrimEnd('/'));
			string content = null;

			var httpClient = new HttpClient();
			httpClient.DefaultRequestHeaders.Add("ApiKey", m_Settings.ApiKey);
			httpClient.GetStringAsync(url).ContinueWith((response) =>
			{
				if (response.Exception != null)
				{
					if (Error != null)
					{
						Error(response.Exception);
					}
				}
				else
				{
					content = response.Result;
				}
			}).Wait(5 * 1000);

			if (content != null)
			{
				var list = Newtonsoft.Json.JsonConvert.DeserializeObject<List<ERPStore.Tasks.ViewModels.Task>>(content);
				return list;
			}

			return new List<Tasks.ViewModels.Task>();
		}

	}
}
